package cn.wolfcode.crm.shiro.realm;

import cn.wolfcode.crm.domain.Employee;
import cn.wolfcode.crm.mapper.EmployeeMapper;
import cn.wolfcode.crm.mapper.PermissionMapper;
import cn.wolfcode.crm.mapper.RoleMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component// 交给Spring管理
public class CRMRealm extends AuthorizingRealm {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    // 注入加密的凭证匹配器
    @Autowired
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }


    // 获取认证信息
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 1.拿到token中的账号
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        // 2.根据用户名查询
        Employee employee = employeeMapper.selectByUsername(token.getUsername());

        // 3.判断对象是否为null
        // 返回null,账户不存在
        if (employee==null) {
            return null;
        }
        // 如果用户不为null,返回真实信息,密码的校验交给securitymanager
        // 参数:1.身份;2.凭证;3.当前Realm的名字,内部getName方法
        // 加盐
        return new SimpleAuthenticationInfo(employee,employee.getPassword(),ByteSource.Util.bytes(employee.getName()),getName());
    }

    /**
     * 获取授权信息
     * @param principalCollection
     * @return 完整的授权信息
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //1.创建授权信息对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //2.拿到之前存入的账户对象
        Employee employee = (Employee)principalCollection.getPrimaryPrincipal();
        if (employee.isAdmin()) {
            //是超级管理员,授予admin角色和所有权限
            info.addRole("admin");
            // *:*不是*.*
            info.addStringPermission("*:*");
        }else {
            //非超级管理员,则要查询数据库得到该用户拥有的角色和权限
            List<String> roles = roleMapper.selectRolesByEmployeeId(employee.getId());
            List<String> expressions = permissionMapper.selectExpressionByEmployeeId(employee.getId());
            info.addRoles(roles);
            info.addStringPermissions(expressions);
        }
        return info;
    }
}
